using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour, IClearable
{
    [Header("----- Repel Details -----")]
    [SerializeField] protected float _hurtRepelForce = 3;
    [SerializeField] protected float _hurtRepelDuration = .2f;

    [Header("----- Chase ----")]
    [SerializeField] private float moveSpeed = 3f;

    [Header("----- Dead Drop -----")]
    [SerializeField] protected float dropExperience;

    [Header("----- Animator Config -----")]
    [SerializeField] private string _animTriggerName;

    [Header("----- Dead Details -----")]
    [SerializeField] private float _rotateAngle = 1000f;
    [SerializeField] private float _deadDuratoin = .5f;
    [SerializeField] private float _deadRepelForce = 1;

    [SerializeField] protected float attackInterval = 2;
    protected WaitForSeconds attackWaitWFX;

    protected Transform chaseTarget;
    protected Rigidbody2D rb;
    private Animator animator;
    protected Enemy_Stat _enemyStat;
    protected bool _canChase;
    protected bool isAttack;
    private float _originalScaleX;

    protected virtual void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        _enemyStat = GetComponent<Enemy_Stat>();
        _originalScaleX = transform.localScale.x;
        attackWaitWFX = new(attackInterval);
    }

    protected virtual void OnEnable()
    {
        chaseTarget = Player.Instance.transform;
        EventCenter.AddEventListener(EventName.PlayerDead, HandlePlayerDead);
        animator.SetTrigger(_animTriggerName);

        _canChase = true;
    }

    private void OnDisable()
    {
        EventCenter.RemoveEventListener(EventName.PlayerDead, HandlePlayerDead);
    }
    private void Update()
    {
        if (_canChase)
            Chase();
    }

    public void Dead(Vector2 hurtDir)
    {
        EventCenter.TriggerEvent(EventName.CollectExp, dropExperience);

        StartCoroutine(DeadCo());
        StartCoroutine(RepelCo(hurtDir, _deadRepelForce, _deadDuratoin));
    }
    private IEnumerator DeadCo()
    {
        float timer = 0;
        Vector3 startAngle = transform.eulerAngles;
        Vector3 startScale = transform.localScale;
        while (timer < _deadDuratoin)
        {
            timer += Time.deltaTime;
            Vector3 currentTargetScale = Vector3.Lerp(startScale, Vector3.zero, timer / _deadDuratoin);
            float currentTargetAngle = Mathf.Lerp(startAngle.z, startAngle.z + _rotateAngle, timer / _deadDuratoin);

            transform.eulerAngles = new(startAngle.x, startAngle.y, currentTargetAngle);
            transform.localScale = currentTargetScale;

            yield return null;
        }
        PoolManager.Instance.Delease(gameObject, () =>
        {
            transform.eulerAngles = startAngle;
            transform.localScale = startScale;
        });
    }

    /// <summary>
    /// 受击击退效果
    /// </summary>
    /// <param name="repelDir"></param>
    public void Repel(Vector2 hurtDir)
    {
        StartCoroutine(RepelCo(hurtDir, _hurtRepelForce, _hurtRepelDuration));
    }
    private IEnumerator RepelCo(Vector2 hurtDir, float repelForce, float repelDuration)
    {
        _canChase = false;

        Vector2 originalVelocity = hurtDir * repelForce;
        rb.velocity = originalVelocity;
        float timer = 0;
        while (timer < repelDuration)
        {
            timer += Time.deltaTime;

            float t = timer / repelDuration;

            float easeT = 1 - (1 - t) * (1 - t);

            rb.velocity = Vector2.Lerp(originalVelocity, Vector2.zero, easeT);

            yield return null;
        }

        _canChase = true;
    }

    /// <summary>
    /// 追击玩家
    /// </summary>
    public void Chase()
    {
        Vector2 moveDir = (chaseTarget.position - transform.position).normalized;
        Vector2 scale = transform.localScale;
        scale.x = moveDir.x > 0 ? _originalScaleX : -_originalScaleX;

        transform.localScale = scale;

        rb.velocity = isAttack ? Vector2.zero : moveDir * moveSpeed;
    }

    public virtual void HandlePlayerDead()
    {
        rb.velocity = Vector2.zero;
        _canChase = false;
        StopAllCoroutines();
    }
    
    public void HandleClear()
    {
        if (gameObject.activeSelf == false)
            return;
            
        StartCoroutine(DeadCo());
    }
}
